﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Xml.Linq;

namespace GroceryInventory
{
    class InventoryModel : INotifyPropertyChanged
    {

        public ObservableCollection<InventoryItem> Items
        {
            get { return _Items; }
            set { _Items = value; }
        }
        private ObservableCollection<InventoryItem> _Items;


        public InventoryItem SelectedInvItem
        {
            get { return _SelectedInvItem; }
            set { _SelectedInvItem = value; }
        }
        private InventoryItem _SelectedInvItem;
        
        #region Constructor

        /// <summary>
        /// Parameterless for Databinding with XAML
        /// </summary>
        public InventoryModel()
        {
            //Load XML somehow and set _Items to list of items in Datasource

            _Items = new ObservableCollection<InventoryItem>();
            if (File.Exists("InventoryTemplate.xml"))
            {
                XDocument main = XDocument.Load("InventoryTemplate.xml");
                
             var items = from t in main.Descendants("Items").Descendants("Item")
				 select new {
                     id = t.Element("ID").Value,
                     name = t.Element("Name").Value,
                     descr = t.Element("Description").Value,
                     units = Int32.Parse(t.Element("Units").Value),
                     count = Int32.Parse(t.Element("Count").Value)
                    };

                foreach(var item in items)
                {
                    _Items.Add(new InventoryItem(item.id, item.name, item.descr, item.units, item.count));
                }

            }
            else
            {
                _Items.Add(new InventoryItem("bananas", "bunches", 5, 1));
                _Items.Add(new InventoryItem("apples", "granny smith", 22, 0));
                _Items.Add(new InventoryItem("ham", "country smoked", 51, 0));
            }

            _SelectedInvItem = new InventoryItem();
        }

        #endregion // Constructor

        #region RelayCommand Methods

        #region AddItem Command Methods

        /// <summary>
        /// Method to determine when a new Item can be added
        /// </summary>
        /// <returns>bool indicating if action is enabled</returns>
        public bool CanAddItemExecute()
        {
            //add code to validate if user can add item
            return true;
        }

        /// <summary>
        /// Execute method for New Item event
        /// </summary>
        public void AddItemExecute()
        {
            //Add code to add item as entered by user
            _Items.Add(new InventoryItem("raisins", "cartons", 800, 0));

        }

        /// <summary>
        /// ICommand for Add Item
        /// </summary>
        public ICommand UpdateAddItemButton
        {
            get { return new RelayCommand(AddItemExecute, CanAddItemExecute); }
        }
        #endregion AddItem Command Methods

        #region DeleteItem Command Methods
        /// <summary>
        /// Method to determine when a new Item can be added
        /// </summary>
        /// <returns>bool indicating if action is enabled</returns>
        public bool CanDeleteItemExecute(object item)
        {
            //add code to validate if user can delete item
            return true;
        }

        /// <summary>
        /// Execute method for New Item event
        /// </summary>
        public void DeleteItemExecute(object item)
        {
            //Add code to add item as entered by user
            _Items.Remove(item as InventoryItem);

        }

        /// <summary>
        /// ICommand for Add Item
        /// </summary>
        public ICommand UpdatDeleteItemButton
        {
            get { return new RelayCommand<object>(DeleteItemExecute, CanDeleteItemExecute); }
        }
        #endregion DeleteItem Command Methods

        #region UpdateItem Command Methods

        /// <summary>
        /// Determines when a transaction can be deleted
        /// </summary>
        /// <param name="parameter"></param>
        /// <returns></returns>
        bool CanUpdateSelectedItem(object parameter)
        {
            // Only allow adding when correct account is logged in
            return _SelectedInvItem != null;
        }

        /// <summary>
        /// Method to delete a transaction
        /// </summary>
        /// <param name="transaction">transaction to delete</param>
        void UpdateSelectedItemExecute(object item)
        {
            InventoryItem iv = item as InventoryItem;
            if ((iv != null) && (_SelectedInvItem != null))
            {
                _SelectedInvItem = iv;
            }
            
            XElement xmlfromlist = new XElement("Items",
                                                 from a in Items
                                                 select
                                                     new XElement("Item",
                                                     new XElement("ID", a.ID),
                                                     new XElement("Name", a.ItemName),
                                                     new XElement("Description", a.Description),
                                                     new XElement("Units",(int)a.Units),
                                                     new XElement("Count", a.Count)));
            xmlfromlist.Save("InventoryTemplate.xml");
            //MessageBox.Show("Nothing has been saved yet");

        }

        /// <summary>
        /// ICommand for Delete Transaction
        /// </summary>
        public ICommand UpdateSelectedItem
        {
            get { return new RelayCommand<object>(UpdateSelectedItemExecute, CanUpdateSelectedItem); }
        }
        #endregion UpdateItem Command Methods

        #region Logging Command Methods
        /// <summary>
        /// Method to determine when log out is available
        /// </summary>
        /// <returns>bool indicating if action is enabled</returns>
        public bool CanLogOutExecute(object item)
        {
            //add code to if type should be logout
            return true;
        }

        /// <summary>
        /// Execute method for log out event
        /// </summary>
        public void LogOutExecute(object item)
        {
            //Add code to log out as entered by user            

        }

        /// <summary>
        /// ICommand for Add Item
        /// </summary>
        public ICommand UpdatLogOutButton
        {
            get { return new RelayCommand<object>(LogOutExecute, CanLogOutExecute); }
        }
        #endregion Logging Command Methods

        #endregion RelayCommand Methods


        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }
        #endregion
    }
}
